﻿using System;
using System.Collections.Generic;
using System.Linq;
using ZY.EntityFrameWork.Core.Context;
using ZY.EntityFrameWork.Core.Repositories.Interface;
using ZY.EntityFrameWork.Core.Model.Entity;
using ZY.EntityFrameWork.Core.Model.Dto;
using ZY.EntityFrameWork.Core.DBHelper;

namespace ZY.EntityFrameWork.Core.Services
{
    /// <summary>
    /// 档案操作类
    /// </summary>
    public abstract class BaseArvOpService : BaseRootService
    {
        public BaseArvOpService(IUnitOfWorkContext unitContext,IArvRepository dal, IArvLocationRepository locRepository, ILendRepository lendRepository, IReturnRepository returnRepository, IOutCabRepository outCabRepository)
            : base(unitContext)
        {
            this.arvRepository = dal;
            this.arvLocationRepository = locRepository;
            this.lendRepository = lendRepository;
            this.returnRepository=returnRepository;
            this.outCabRepository = outCabRepository;
        }

        public BaseArvOpService()
        {
            arvRepository = UnityHelper.Instance.Resolve<IArvRepository>();
            arvLocationRepository = UnityHelper.Instance.Resolve<IArvLocationRepository>();
            lendRepository = UnityHelper.Instance.Resolve<ILendRepository>();
            returnRepository = UnityHelper.Instance.Resolve<IReturnRepository>();
            outCabRepository = UnityHelper.Instance.Resolve<IOutCabRepository>();
        }
        
        //所需要的数据访问
        private IArvRepository arvRepository { get; set; }
        private IArvLocationRepository arvLocationRepository;
        private ILendRepository lendRepository;
        private IReturnRepository returnRepository;
        private IOutCabRepository outCabRepository;

        #region 位置信息
        /// <summary>
        /// 判断位置信息是否已经存在
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool CheckLocationExists(ArvLocation model)
        {
            return arvLocationRepository.CheckExists(loc => loc.GroupNo == model.GroupNo && loc.LayerNo == model.LayerNo);
        }

        public int AddNewLocation(ArvLocation model)
        {
            if (CheckLocationExists(model))
            {
                throw new Exception("试图添加已存在的位置信息");
            }
            return arvLocationRepository.Insert(model);
        }

        public int AddNewLocations(List<ArvLocation> models)
        {
            models.ForEach(q =>
                {
                    if (CheckLocationExists(q))
                    {
                        throw new Exception("试图添加已存在的位置信息");
                    }
                });
            return arvLocationRepository.Insert(models);
        }

        #endregion

        #region 入库相关

        /// <summary>
        /// 查找在库档案
        /// </summary>
        /// <returns></returns>
        public List<ArchiveInfo> GetArvInLib()
        {
            //IQueryble无法映射，可能是因为它在枚举之前是并没有加载数据的原因，其他地方都要换成List或Inumerable
            return arvRepository.Find(q => q.ArvStatus == "在库").ToList();
            //return arvRepository.Find(q => q.ArvStatus == "在库").AsQueryable().MapTo<IQueryable<ArchiveInfoDto>>();
        } 

        /// <summary>
        /// 档案入库
        /// </summary>
        /// <param name="arv"></param>
        public int InputToLib(ArchiveInfo arv)
        {
            if(arvRepository.CheckExists(q=>q.ArvID==arv.ArvID))
            {
                throw new Exception("试图添加档案编号重复的记录");
            }
            arv.ArvStatus = "在库";
            return arvRepository.Insert(arv);
        }

        /// <summary>
        /// 多条档案同时入库
        /// </summary>
        /// <param name="arvs"></param>
        /// <returns></returns>
        public int InputToLib(List<ArchiveInfo> arvs)
        {
            arvs.ForEach(q =>{
                if (arvRepository.CheckExists(t => q.ArvID == t.ArvID))
                {
                    throw new Exception("试图添加档案编号重复的记录");
                }
                q.ArvStatus = "在库";
                
            });
            return arvRepository.Insert(arvs);
        }

        /// <summary>
        /// 单个档案放入柜中(后期看情况第二个参数改成档案盒编号)
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="locDto"></param>
        /// <returns></returns>
        public int InputToCab(ArchiveInfo model,ArvLocation locModel)
        {
            ArvLocation loc = arvLocationRepository.FindSingle(q => q.GroupNo == locModel.GroupNo && q.LayerNo == locModel.LayerNo).MapTo<ArvLocation>();
            if (loc == null)
            {
                throw new Exception("位置信息不存在");
            }
            model.ArvStatus = "在柜";
            model.ArvLocation = loc;
            return arvRepository.Update(model);
        }

        /// <summary>
        /// 多个档案放入同一位置
        /// </summary>
        /// <param name="arvs"></param>
        public int InputToCab(List<ArchiveInfo> arvs, ArvLocation locModel)
        {
            //取出数据库中的对应位置，否则更新时会自动再增加一个位置
            ArvLocation loc = arvLocationRepository.FindSingle(q => q.GroupNo == locModel.GroupNo && q.LayerNo == locModel.LayerNo).MapTo<ArvLocation>();
            if (loc == null)
            {
                throw new Exception("位置信息不存在");
            }
            //指定位置
            arvs.ForEach(q => { q.ArvStatus = "在柜"; q.ArvLocation = loc; });
            return arvRepository.Update(arvs);
        }
        #endregion

        #region 借阅相关
        /// <summary>
        /// 查找在柜档案
        /// </summary>
        /// <returns></returns>
        public List<ArchiveInfo> GetArvInCab()
        {
            return arvRepository.Find(q => q.ArvStatus == "在柜").ToList();
        }

        public int ArvLend(LendInfo lendInfo, List<ArchiveInfo> infos)
        {
            infos.ForEach(q =>
            {
                q.ArvStatus = "借出";
                LendInfo info = lendInfo;
                info.ArvID = q.ArvID;
                lendRepository.Insert(info, false);
                arvRepository.Update(q, false);
            });
            return Context.Commit();
        }

        #endregion

        #region 归还相关
        /// <summary>
        /// 查找被借阅的档案
        /// </summary>
        /// <returns></returns>
        public List<ArchiveInfo> GetArvLended()
        {
            return arvRepository.Find(q => q.ArvStatus == "借出").ToList();
        }

        public int ArvReturn(ReturnInfo returnInfo, List<ArchiveInfo> arvInfos)
        {
            arvInfos.ForEach(q =>
            {
                q.ArvStatus = "在柜";
                arvRepository.Update(q, false);
                ReturnInfo info = returnInfo;
                info.ArvID = q.ArvID;
                returnRepository.Insert(returnInfo, false);
;                
            });
            return Context.Commit();
        }
        #endregion

        #region 出柜相关

        public int ArvOutput(OutCabInfo outInfo, List<ArchiveInfo> arvInfos)
        {
            arvInfos.ForEach(q =>
            {
                q.ArvStatus = "在库";
                OutCabInfo outModel = outInfo;
                outModel.ArvID = q.ArvID;
                arvRepository.Update(q, false);
                outCabRepository.Insert(outModel, false);
            });
            
            return Context.Commit();
        }

        #endregion

    }
}
